package com.jumi.microservice.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jumi.microservice.common.constant.ResultEnum;
import com.jumi.microservice.common.exception.BaseException;
import com.jumi.microservice.constant.*;
import com.jumi.microservice.domain.ActivityGoodsBrandDTO;
import com.jumi.microservice.domain.BrandDO;
import com.jumi.microservice.domain.BrandDTO;
import com.jumi.microservice.domain.GoodsDO;
import com.jumi.microservice.mapper.BrandMapper;
import com.jumi.microservice.mapper.GoodsMapper;
import com.jumi.microservice.service.BrandService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 商城品牌表 服务实现类
 * </p>
 *
 * @author liuz
 * @since 2020-07-27
 */
@Service
@Transactional
public class BrandServiceImpl extends ServiceImpl<BrandMapper, BrandDO> implements BrandService {

    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 新增品牌
     * @param dto
     */
    @Override
    public void insert(BrandDTO dto) {
        BrandDO po = dto2Po(dto);
        ExceptionEnum.FAIL_BRAND_NULL.doThrowIf(po==null);
        //判断品牌名称是否存在
        int count = baseMapper.selectCount(
                Wrappers.<BrandDO>lambdaQuery()
                        .eq(BrandDO::getBrandName,po.getBrandName())
                        .eq(BrandDO::getIsDel,StatusEnum.STATUS_NO.getCode()));
        ExceptionEnum.FAIL_BRAND_EXIST.doThrowIf(count>NumberConstant.NUMBER_ZERO);
        LocalDateTime now = LocalDateTime.now();
        po.setCreateTime(now);
        po.setUpdateTime(now);
        baseMapper.insert(po);
        saveOrRemoveBrandRedis(po, 1, null);
    }

    /**
     * 删除品牌
     * @param ids 主键id
     * @param username 操作用户名
     */
    @Override
    public void delete(String ids, String username) {
        ExceptionEnum.FAIL_ID_NULL.doThrowIf(ids==null);
        //判断品牌是否有启动状态的
        String[] idss = ids.split(",");
        Arrays.stream(idss).forEach(id->{
            //判断是否有商品已绑定
            int gcount = goodsMapper.selectCount(
                    Wrappers.<GoodsDO>lambdaQuery()
                            .eq(GoodsDO::getBrandId,id)
                            .eq(GoodsDO::getIsDel, StatusEnum.STATUS_NO.getCode()));
            if(gcount>NumberConstant.NUMBER_ZERO){
                throw new BaseException(new IResponseRxceptionCode(ResultEnum.FAIL.getCode(), StrUtil.format(ExceptionEnum.FAIL_BRAND_BIND_GOODS.getMessage(),id)));
            }
            //jumi5.0 判断是否绑定优品
            if(redisTemplate.hasKey(GoodsKeyConstant.ACTIVITY_GOODS_BRAND_EXIST+id)){
                throw new BaseException(new IResponseRxceptionCode(ResultEnum.FAIL.getCode(), StrUtil.format(ExceptionEnum.FAIL_BRAND_BIND_ACTIVITY.getMessage(),id)));
            }
            //判断是否为启用状态
            BrandDO po = baseMapper.selectById(id);
            if(po!=null&&po.getStatus()==StatusEnum.STATUS_YES.getCode()){
                throw new BaseException(new IResponseRxceptionCode(ResultEnum.FAIL.getCode(), StrUtil.format(ExceptionEnum.FAIL_BRAND_SOURCE.getMessage(),po.getId())));
            }
            po.setIsDel(StatusEnum.STATUS_YES.getCode());
            po.setUpdateTime(LocalDateTime.now());
            po.setModifier(username);
            baseMapper.updateById(po);
        });
        saveOrRemoveBrandRedis(null, 0, ids);
    }

    /**
     * 编辑品牌
     * @param dto
     */
    @Override
    public void updateBr(BrandDTO dto) {
        Long st = System.currentTimeMillis();
        BrandDO po = dto2Po(dto);
        ExceptionEnum.FAIL_BRAND_NULL.doThrowIf(po==null);
        //判断品牌名称是否存在
        int count = baseMapper.selectCount(
                Wrappers.<BrandDO>lambdaQuery()
                        .eq(BrandDO::getIsDel,StatusEnum.STATUS_NO.getCode())
                        .eq(BrandDO::getBrandName,po.getBrandName())
                        .ne(BrandDO::getId,po.getId()));
        ExceptionEnum.FAIL_BRAND_EXIST.doThrowIf(count>0);
        po.setUpdateTime(LocalDateTime.now());
        baseMapper.updateById(po);
        saveOrRemoveBrandRedis(null, 0, po.getId().toString());
        saveOrRemoveBrandRedis(po, 1, null);
    }

    /**
     * 品牌启用/禁用
     * @param id 主键id
     * @param status 状态，1启用，0.禁用
     * @param username 操作用户名
     */
    @Override
    public void enableStaus(Long id, Integer status, String username) {
        ExceptionEnum.FAIL_ID_NULL.doThrowIf(id==null);
        BrandDO brand = baseMapper.selectById(id);
        ExceptionEnum.FAIL_ID_NULL.doThrowIf(brand==null);
        brand.setModifier(username);
        brand.setUpdateTime(LocalDateTime.now());
        brand.setStatus(status);
        baseMapper.updateById(brand);
//        saveOrRemoveBrandRedis(brand, status, brand.getId().toString());
    }

    /**
     * 品牌详情
     * @param id 主键id
     */
    @Override
    public BrandDTO selectById(Long id) {
        ExceptionEnum.FAIL_ID_NULL.doThrowIf(id==null);
        return po2Dto(baseMapper.selectById(id));
    }

    /**
     * dto->po
     * @param dto
     * @return
     */
    private BrandDO dto2Po(BrandDTO dto){
        BrandDO po = null;
        try {
            po = dto.clone(BrandDO.class);
        }catch (Exception e){
            ExceptionEnum.FAIL_CHANGE.newException();
        }
        return po;
    }

    /**
     * po->dto
     * @param po
     * @return
     */
    private BrandDTO po2Dto(BrandDO po){
        BrandDTO dto = null;
        try {
            dto = po.clone(BrandDTO.class);
        }catch (Exception e){
            ExceptionEnum.FAIL_CHANGE.newException();
        }
        return dto;
    }

    /**
     * 添加/删除品牌redis
     * @param brand 品牌信息
     * @param type 操作: 0:删除,1:添加
     * @param ids 批量操作id
     */
    private void saveOrRemoveBrandRedis(BrandDO brand, Integer type, String ids){
        ActivityGoodsBrandDTO activityGoodsBrandDTO = null;
        Object o = redisTemplate.opsForValue().get(GoodsKeyConstant.ACYTIVITY_GOODS_BRAND);
        if(ObjectUtil.isNotNull(o)){
            List<ActivityGoodsBrandDTO> brands = (List<ActivityGoodsBrandDTO>) o;
            if(1==type){
                activityGoodsBrandDTO = new ActivityGoodsBrandDTO();
                BeanUtil.copyProperties(brand, activityGoodsBrandDTO);
                brands.add(activityGoodsBrandDTO);
                redisTemplate.opsForValue().set(GoodsKeyConstant.ACYTIVITY_GOODS_BRAND, brands);
            }else{
                List<ActivityGoodsBrandDTO> newBrands = brands.stream().filter(br->!ids.contains(br.getId().toString())).collect(Collectors.toList());
                redisTemplate.opsForValue().set(GoodsKeyConstant.ACYTIVITY_GOODS_BRAND, newBrands);
            }
        }else{
            if(1==type) {
                List<ActivityGoodsBrandDTO> brands = new ArrayList<>();
                activityGoodsBrandDTO = new ActivityGoodsBrandDTO();
                BeanUtil.copyProperties(brand, activityGoodsBrandDTO);
                brands.add(activityGoodsBrandDTO);
                redisTemplate.opsForValue().set(GoodsKeyConstant.ACYTIVITY_GOODS_BRAND, brands);
            }
        }
    }

}
